Skip to content

Ask a few questions when a Magic Compose description doesn't say what people sign up for - #577

Merged
richshaw merged 23 commits into
claude/pensive-thompson-quytut-4-screenfrom
claude/pensive-thompson-quytut-5-prompt
Oct 27, 2026
Merged

richshaw merged 23 commits into
claude/pensive-thompson-quytut-4-screenfrom
claude/pensive-thompson-quytut-5-prompt

Conversation

@richshaw

@richshaw richshaw commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Fixes #570, the last of five stacked PRs. It's based on #576 (the questions screen). This is the PR that turns the questions on. Merge it together with #576.

The problem

A Magic Compose description that's only an event's name, like "Bake sale", gives the model nothing to build slots from. It either makes three "TBD" rows or invents jobs and counts, and the organizer still uses one of the hour's drafts.

The fix

The prompt

Rule 4 (the drafter's never-invent text, NEVER_INVENT_MIDDLE.drafter in signup-rules.ts) now splits the cases:

If the prompt doesn't say what people sign up for (e.g. "make a signup for my kid's soccer team") and carries no answers to your questions, don't draft: ask, with the QUESTIONS reply. Named items, roles or tasks, or dated practices, sessions or shifts, already say what: draft, don't ask. An event with no item or role ("family movie night on March 3") doesn't: ask. If it says what but not when or how many (e.g. "snack duty for the soccer team"), draft anyway: where the slots need dates or times it doesn't give, produce 1-3 placeholder slots with labels like "TBD: game 1"…

RULES_IN_BOTH and the AI connector's instructions are unchanged, and their tests prove it.

A QUESTIONS section after the output schema gives the reply shape and its rules. It applies only when the prompt doesn't say what people sign up for (rule 4):

  • list only the topics the prompt leaves out, always with "what";
  • offer 2 to 4 options, in the prompt's language, each at most 40 characters;
  • never offer a date, a time or a count;
  • if the options would be the prompt's own items or roles, draft instead;
  • never ask when a message carries "Answers to your questions:".

Capacity is <integer, 1 by default; null only if the prompt or answers say there's no limit>. Rule 9 ends: No limit ("unlimited", "as many as want") means null; never null as a guess. The follow-up message's "no limit" relies on null.

The worked examples:

  • Example C, the vague soccer prompt, now asks: {"questions":{"topics":["what","when","how_many"],"whatOptions":["Bring snacks","Drive to away games","Help at practice"]}}.
  • A new Example D ("Ushers for the school play, two parents per performance") says what but not when, so it still drafts TBD: performance 1–3 with 2 spots each. Find fixable problems in a draft and offer one-tap fixes #503 relies on those "TBD:" rows.
  • A new Example E (gear families could lend for a camping trip) lists what with no date or count, so it drafts four slots with no date field.

The golden file is regenerated; its diff is only these changes. A test parses every worked example with the server's schema, and another fails when a worked example or a rule's "e.g." matches an eval prompt, whole words only, so no case scores recall of the prompt's own words.

Evals

The harness (scripts/lib/eval-harness.ts, scripts/eval-magic-compose.ts):

  • A questions result arm.
  • New outcomes:
    • unexpected_questions;
    • expected_questions_but_drafted;
    • asked_again: questions in reply to the answers, in any shape, read with the route's own asksQuestions.
  • New checks: questions.must_ask (true or false), topics_must_include, topics_must_not_include, topics_must_equal, options_count_range, options_must_not_contain_date_or_number (English and French number words, months and weekdays), options_must_mention_any and options_must_not_mention_any.
  • slot_dates.* counts only real days, with the converter's own isRealDate, so a "TBD: date 1" placeholder or a weekday in a date field isn't a date.
  • A case with answers (a FollowUp) is checked with FollowUpSchema before any model call. The first call must ask. Then the answers go through buildFollowUpMessages, as in the route, and the draft is scored.
    • Only the asked topics are sent: when only if the first call asked "when", howMany only if it asked "how_many".
    • A failed second call is reported as "second call: …", with the first call's checks still shown.
  • answers is a new key because followUps already means the MCP runner's organizer turns.
  • scripts/lib/eval-harness.test.ts tests the harness's own logic. For it to run, vitest.config.ts now includes scripts/**/*.test.ts.

pnpm eval:mcp loads the same file:

  • On a case where Magic Compose asks, an assistant that asks instead of creating passes as asked_before_creating: with a "?", or a request for details in so many words ("Please share the dates…", "I'll need…"). An empty reply, a refusal (even one closing "Let me know what else…") and a create fail.
  • answers cases are skipped.

Cases. #526 added ev_027 (the classroom starter), so this PR's new cases are ev_028–ev_037. ev_008 flips from "drafts 1–6 slots" to "asks", with a swim club prompt of its own (it used to be Example C word for word). ev_002 accepts a quantity or amount field.

id prompt expected
ev_028 "Bake sale" asks
ev_029 "Class picnic" asks
ev_030 "Team party on Saturday, June 5" asks, but not about the date
ev_031 the French prompt asks, with options in French about the bake sale
ev_032 a dish list drafts
ev_033 a full potluck drafts
ev_034 snack duty for the basketball team drafts "TBD:" rows
ev_035 conferences drafts "TBD:" rows
ev_036 drafts from answers those items, that date and those counts, with null for no limit
ev_037 Draft with placeholders drafts "TBD:" rows

Quota

magicComposePerOrganizer goes from 10 to 12 an hour. A thin description now takes two AI calls: the first, and the one with the answers. The free retries don't count. No docs or pages named the old number.

Privacy and changelog

The privacy page already says the answers go to the AI provider (#573). CHANGELOG has a line under Added.

Your two open questions

I took the issue's defaults:

  • a missing date alone doesn't ask;
  • the hourly limit goes to 12.

Evals

The owner's run over Flash and a panel of nine models (in the comments) found the prompt asked about prompts that already list what people sign up for, null capacity where nobody said "no limit", ev_008 copying Example C, and four harness bugs. All are fixed above. The new wording hasn't met a real model yet (this session has none), so please run again, on this branch and on main:

pnpm eval:magic-compose
pnpm eval:magic-compose --tag=questions
pnpm eval:mcp

Watch:

  • ev_001–027 and ev_032–035 for asking where they used to draft;
  • ev_004 (a schedule of practices, which should draft);
  • ev_030 (a single dated event, which should still ask, without "when");
  • how often capacity is null;
  • ev_008 and ev_034 with their new prompts.

Reviews

  • The first review, fixed in e4b58cd:
    • rule 4 had no exception for a message carrying answers;
    • Example D's prompt was word for word an eval case's.
  • A second review (/code-review), fixed in 7b78492. It found eight harness issues:
    • a partial re-ask was scored as a parse failure;
    • must_ask: false meant the opposite;
    • the MCP runner passed any reply on an ask-case;
    • French counts got through;
    • bad case answers were checked only after a paid call;
    • unasked topics were still sent;
    • a dead branch;
    • a second-call failure hid the first call's checks.
  • The owner's eval run, fixed in 1793483, 3ff77f3, b4b1fbd and cc9fc83 (rule 4, Example E, the capacity line, ev_008, the four harness bugs). An advisor read of the new wording led to cc9fc83 (the counter-case, and options "the prompt's own items or roles" rather than anything it lists).
  • A /code-review of that, fixed in 82c6a92: ev_031 counted words English shares, the MCP check passed a refusal's closing line, slot_dates counted non-dates, ev_034 held rule 4's "e.g.", and quoting "no limit" could read as the exact words only.
  • Left as is:
    • The eval doesn't repeat the route's retries. That's deliberate: it measures the first reply.
    • ev_008's check bans "soccer" and "away games" but not "Bring snacks" or "Help at practice", which are fair options for a swim club too.
  • Formatting: Prettier also re-wrapped some existing lines in eval-harness.ts, eval-mcp.ts and the README, files this PR already rewrites.

Tophat

On this branch, against the fake endpoint:

  • the server sends the merged system prompt, with both the QUESTIONS and CAPACITY sections;
  • the full flow (description → questions → answers → draft in the builder) works with no console errors;
  • the 12th draft in an hour goes through and the 13th gets the friendly limit message.

Tests

pnpm lint && pnpm typecheck && pnpm knip && pnpm test (1988) and pnpm test:db (623) pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks

The Magic Compose prompt now describes the questions reply and when to
use it: only when the prompt doesn't say what people sign up for, listing
only the topics it leaves out, with two to four options in the prompt's
language and never a date or a count, since the app asks for those
itself. A message that carries the organizer's answers is never answered
with questions.

The drafter's never-invent rule splits in two. No "what" asks; a prompt
that says what but not when or how many still drafts "TBD:" rows, which
the builder's placeholder checks rely on. Example C, the vague soccer
prompt, becomes a questions reply, and a new Example D keeps the
placeholder pattern for "Snack duty for the soccer team, two families per
game". The prompt also says capacity may be null, which is where the
follow-up's "no limit" lands. RULES_IN_BOTH and the assistant's rule are
untouched, so the MCP server instructions don't change.

The golden file is regenerated. A new test parses every worked example
with the server's schema, and others hold the prompt to the follow-up
message's label and its "no limit".

Part of #570.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
The eval script treated a questions reply as a failed call, so nothing
measured whether the prompt asks when it should. The harness gains a
questions arm: a case with questions.* checks expects one (a draft fails
as expected_questions_but_drafted), and questions anywhere else fail as
unexpected_questions, as a stray refusal does. The checks cover the
topics asked (include, exclude, equal), the number of options, options
holding a date or a number, and whole-word matches on the options, which
the French case uses to check they are in French.

A case with `answers` runs both calls the page makes: the prompt, which
must ask, then the prompt with the answers through FollowUpSchema and
buildFollowUpMessages, whose draft the existing checks score. Questions
there fail as asked_again. It is a new key because followUps already
means organizer turns in the MCP runner.

ev_008 now expects questions instead of 1-6 placeholder slots, and ten
made-up cases cover name-only prompts, a date with no "what", a French
prompt, near misses that must still draft (with "TBD:" rows where the
slots need dates), and drafts from answers and from Draft with
placeholders.

pnpm eval:mcp reads the same file. An assistant that asks the organizer
is right where Magic Compose would ask, so there a reply passes as
asked_before_creating; "assistant_may_ask" marks the two placeholder
cases where an assistant may ask for the dates instead; cases with
answers are skipped. Every existing case scores as before.

Part of #570.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
Both calls of a questions round reach the AI, so both count: a
description that gets questions now uses two drafts. Two more an hour
make up for a couple of those. The route's comment no longer names the
number, so it can't go stale again.

Part of #570.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
When the description doesn't say what people sign up for, the organizer
now answers a few questions and the answers are sent to the AI provider
with it. The privacy page's Third parties paragraph says so; it still
names nothing else about the organizer and nothing about participants.
The Last updated date is already today's.

The CHANGELOG gains the line for the questions round being on: what asks
and what still drafts, the quota going to 12 an hour, and the evals,
with ev_008 now expecting questions.

Part of #570.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
…al from copying an example

Rule 4 told the drafter to ask whenever a prompt doesn't say what people
sign up for, with the exception only in the QUESTIONS section. Draft with
placeholders sends exactly that ("What people sign up for: not given"),
so it was the follow-up most likely to be asked again. The rule now says
"and carries no answers to your questions" itself.

Example D's prompt was word for word ev_033's, so that case measured
copying the example rather than the rule. Example D is now school play
ushers, two parents per performance; ev_033 keeps the design's snack duty
prompt. Golden file regenerated; the diff is these two changes.

Part of #570.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
The review of the eval harness found it disagreeing with the route and the
page in a few places, so its scores could mislead.

A reply to the answers that asks again with only part of a question (just
"when", say) was scored as a broken draft. It is now asked_again, read with
asksQuestions as the route reads it. The second call now sends "when" and
"how many" only when the first call asked about them, as the page does; when
the first call drafted instead, the answers still go back as written. A
case's answers are checked with FollowUpSchema before any paid call, and a
bad one is reported as a broken case rather than an LLM failure. When the
second call fails, its error says "second call:" and the first call's checks
are still printed.

"questions.must_ask": false now expects a draft instead of counting as a
questions case. In eval:mcp a reply passes an ask case only when it asks
something (holds a "?"), so a refusal or an empty reply fails. French number
words join the date-or-number check for the French case. asksFirst loses a
branch nothing could reach.

The harness gets its own unit tests, so vitest now also runs
scripts/**/*.test.ts. The changed files are run through prettier.

Part of #570.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
#526 added its own ev_027 (the classroom starter), so this branch's new
cases are renumbered ev_028 to ev_037; the README follows. The prompt
and its golden file merge cleanly: #526's CAPACITY section and this
branch's QUESTIONS section both render, and the golden-file test passes.
The quota line keeps 12 beside #525's link-events limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
Through the server, telemetry and screen branches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
…he 5-prompt branch

Through the server, telemetry and screen branches. rate-limit.ts keeps
this branch's 12 drafts an hour and main's reworded link-beacon
comment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
Through the server, telemetry and screen branches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
Through the server, telemetry and screen branches. No conflicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
@richshaw

Copy link
Copy Markdown
Owner Author

Tophat and evals: the prompt that asks

The app. I ran b8f2e66 locally with pnpm dev, Postgres 16, Chromium, and Gemini Flash through OpenRouter. The full flow works, and so do the retry, asked_again, the 12th and 13th draft of the hour, and every activity row. #576 has the screen details.

The server sends the merged system prompt, with both QUESTIONS and CAPACITY. The follow-up message matches #573's format word for word. The server log holds no description or answer text.

Borderline prompts on Flash (made up, 3 tries each):

  • Drafts: "Field trip chaperones, 4 needed" and "Carpool for swim meets". The starter examples still draft too.
  • Asks: "Volunteers needed" and "Teacher appreciation week". "Help at the school fun run on May 2" asks without "when". "Vente de gâteaux pour l'école" asks with French options.
  • Either: "Book fair volunteers" asked once and drafted TBD rows twice.

The evals you asked for. Flash ran 3× per side. A panel of 9 OpenRouter models also ran 3× per side: llama-3.3-70b, llama-3.1-8b, mistral-small-3.2, qwen3-30b-a3b, gemma-3-27b, gpt-oss-120b, deepseek-v4-flash, gpt-4o-mini and claude-haiku-5.5. The comparison is b8f2e66 against main at 4816dc4, plus eval:mcp once per side on Flash. P-values are Fisher's exact test.

The three cases you asked to watch pass on Flash, 4 of 4 each:

  • ev_037: asks, then drafts TBD rows and never asks again.
  • ev_030: leaves "when" out.
  • ev_031: gives French options.

Good

  • Asks where it should. 158 of 189 panel replies on the thin prompts (84%) were valid questions. None offered a date or a number, and every one asked all three topics where all three were missing.
  • Never asks again after answers. There was no asked_again in 48 real second calls. ev_036's counts were right 27 of 27 times.
  • Placeholders improved. On ev_034, 19 of 20 drafts were all TBD rows, against 15 of 26 on main, and none invented dates (main did 3 times).
  • main bears out the issue. On the thin prompts, 67% of its drafts are all TBD rows and 33% invent items.

To fix

  1. It asks about prompts that already list what people sign up for. This is the main regression.
    • On ev_001–027, 27 of 621 panel replies are questions, against 0 of 621 on main (p=1e-8). On the near misses ev_032–035 it's 24 of 108, against 0 (p=3e-8).
    • The worst were qwen3-30b (12 of 69), plus gpt-4o-mini and mistral (6 of 12 on the near misses). Flash asked on none of the near misses.
    • The model hands the prompt's own items back as options. Here is qwen on ev_001, the supplies list: {"questions":{"topics":["what","how_many"],"whatOptions":["Tissues","Hand sanitizer","Glue sticks","Washable markers"]}}.
    • A fix: rule 4 could say that a list of items, roles or tasks is what people sign up for, and a worked example could show an item list with no date that drafts.
  2. A questions reply with the wrong shape becomes an error. 6 of 245 questions replies failed QuestionsSchema: deepseek and mistral asked only ["when","how_many"] when "what" was already known, and gpt-oss offered 5 options. The organizer gets the old "AI draft did not match expected shape — try again or adjust your prompt". The call is charged and nothing retries; I reproduced that through the route with a canned one-option reply. A retry like the follow-up's, or keeping only the first 4 options, would cover most of it.
  3. ev_008 is Example C word for word, so it measures recall: 23 of 31 asks copy Example C's options exactly. This PR fixed the same overlap for Example D. Change ev_008's prompt, or Example C's.
  4. Eval harness bugs:
    • slot_dates.* reads "TBD: date 1" as a date, so ev_037 fails when it shouldn't (gpt-4o-mini 3 of 3, gemma 1 of 3).
    • The MCP "?" heuristic failed a real request that had no "?" (Flash, ev_034).
    • ev_031's French check passes on articles alone, so off-topic French gets through.
    • ev_002's matcher still rejects a quantity field.

Your call

  • Flash now asks on ev_004 ("U12 baseball practice every Tuesday and Thursday …"). It asks 6 of 6 times, plus 3 of 3 in the tophat. main drafts the right 14 slots 6 of 6 times (p=0.002). The options are sensible ("Player attendance", "Assistant coaching", "Snack duty"), and the prompt doesn't say what people sign up for. So either the behaviour or ev_004's expectation should change.
  • null capacity shows up where the prompt never said "no limit". That's 84 of 518 panel drafts (16%), against 0 of 538 on main (p=3e-28). Flash does it 7 of 60 times, and so does every other model. It comes from the new schema line "capacity": <integer, 1 by default, or null for no limit>. For example, Haiku on ev_002 (80 cookies) gives quantity: 80 with capacity: null. That's arguably right for item lists, and arguably against "defaults to 1".
  • Drafts got slightly worse on ev_001–027. Measured on what each case is about, they pass 83% of the time against 88% on main (p=0.017). The drop is mostly the two llamas. Haiku, deepseek, gpt-oss and gpt-4o-mini are flat.

Weak spots, for the record:

  • llama-3.1-8b asks only 4 of 21 times.
  • ev_030 asks 14 of 27 times; the other drafts invent items or times.
  • 8 of 27 ev_036 drafts split 9 to 1 into hourly shifts (gemma and the llamas).
  • gpt-4o-mini turns the given time into "TBD" 3 of 3 times.

Related, older than this stack: one-day drafts keep the date in the description and get no Date column, so their reminders never go out. With the plain description it happened 6 of 6 times on Flash. After this stack's "One day" answer it happened 3 of 8 times. Filed as #685, to follow this PR.

The evals made 2,239 calls for $3.40.


Generated by Claude Code

…ty for "no limit"

An eval run over many models found the questions round asking about
prompts that already say what people sign up for: a supplies list got
questions whose options were the list's own items. Rule 4 now says that
a list of items, roles, tasks or dishes, or a schedule of dated sessions,
practices or shifts, already says what, so the drafter drafts. The
QUESTIONS section points back to rule 4, and an option that would repeat
something the prompt lists is the sign to draft instead. Example E shows
an item list with no date or count drafted as it stands: no date field,
no placeholders, capacity 1.

The same run found null capacities on drafts whose prompts never said
"no limit", traced to the schema line offering null beside the default.
The line and rule 9 now keep null for a prompt or answers that say
"no limit", which the follow-up message still sends for an empty count
box, and say a count that isn't given is 1.

Golden file rewritten from the new prompt; its diff is these changes.
The MCP instructions and RULES_IN_BOTH are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
…ample C

ev_008 was Example C's prompt word for word, so it measured whether a
model recalls the example: in the owner's eval run most replies that
asked copied Example C's options. It is now a different vague signup
with no "what" (a swim club), with the same expectations, plus a check
that its options aren't the soccer team's ("away games" don't fit a swim
club).

A test in prompt.test.ts now fails when a worked example's prompt is, or
holds, an eval case's, and the evals README says why.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
The owner's eval run turned up checks that failed good replies or passed
bad ones:

- slot_dates.* read a "TBD: date 1" placeholder in a date field as a
  date, so ev_037 failed a draft that invented nothing. A TBD value is
  now no date, as it is to the converter.
- eval:mcp passed an assistant that asked instead of creating only when
  its reply held a "?", and failed a real request phrased without one.
  The check now lives in the harness (askedBeforeCreating) and also
  takes a short list of requests for details ("Let me know the dates",
  "Please share...", "I'll need the dates"). An empty reply still
  fails, and so does one that asks for nothing, such as a refusal that
  ends "Let me know if there's anything else".
- ev_031 accepted any option holding a French article or a verb that
  fits any signup, so off-topic French passed. It now needs a word
  about the bake sale itself (cakes, the sale, its stand or drinks).
- ev_002 rejected a number field named "quantity" (or "amount"), a
  reasonable way to give 80 cookies, 40 brownies and 30 cupcakes.

Each fix has a test in eval-harness.test.ts, the case fixes against the
cases as they stand in dev-evals.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
An advisor read of the new prompt found two risks for small models. Rule
4's new sentence said a schedule of dated sessions already says what, so
a lone dated event such as "Team party on Saturday, June 5" could now
draft; it now names an event with no item or role as the case that
still asks. And "if an option would repeat something the prompt lists"
could read as "Bake sale" → "Bake something to sell", which the
questions evals need; it now speaks of the prompt's own items or roles.
Rule 9 says the same as before in fewer words.

The golden file is rewritten to match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
A review of the prompt and eval fixes found:
- ev_031's word list counted "stand", "table", "biscuits" and "crepes",
  which are English too, so English options passed the French case.
- The asked-first check passed a refusal that closed with "Let me know
  what else I can help with" or "Please tell me if you'd like…".
- slot_dates counted any date value but a TBD one, though the converter
  keeps only real days, so a weekday or "TBD (2026-06-06)" in a date
  field was scored as a date. It now uses the converter's isRealDate.
- ev_034's prompt held rule 4's own e.g., "snack duty for the soccer
  team", as ev_008 held Example C. It is now the basketball team, and
  the guard test checks the rules' e.g. snippets too, word by word.
- Quoting "no limit" in the schema line and rule 9 could read as the
  exact words only, so "unlimited" or "as many as want" would get
  capacity 1. Both now say "there's no limit", with those as examples.

The golden file is rewritten to match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
Brings in the questions screen's review fixes, the first call's retry
for questions of the wrong shape and the privacy page's date. The
CHANGELOG keeps this branch's line, now saying what counts as saying
what, the first reply's retry and when a slot has no limit, beside the
telemetry line's updated placeholders meaning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks
Through the server, telemetry and screen branches. No conflicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UW9ZpEu4MWkeqTv2Qe14ks

Copy link
Copy Markdown
Owner Author

Thanks for the eval run. It found what my fake endpoint couldn't. Everything below is pushed. I can't run a real model here, so the new wording needs another eval run before merging.

To fix

  1. It asked about prompts that already list what people sign up for. Changes are in 1793483 and cc9fc83, and 82c6a92 changes the no-limit wording (3rd bullet).
    • Rule 4 (drafter only; the MCP side is unchanged) now has a sentence for this, and a case that should still ask:

      Named items, roles or tasks, or dated practices, sessions or shifts, already say what: draft, don't ask. An event with no item or role ("family movie night on March 3") doesn't: ask.

    • The options line says: "If the options would be the prompt's own items or roles, it already says what: draft instead." An advisor read flagged that a looser version ("repeat something the prompt lists") could make "Bake sale" draft, so I narrowed it.
    • The QUESTIONS heading now starts "only when the prompt doesn't say what people sign up for (rule 4)".
    • A new Example E shows an item list with no date that drafts (gear to lend for a camping trip). No eval prompt mentions any of its words.
  2. A questions reply in the wrong shape became an error. This is fixed in Let Magic Compose answer with questions, and draft from the answers #573 (2e85bcf, b09eb57).
    • Five options, or a repeat, keep the first four different ones. A blank or over-long option, and a topic the page doesn't know, are dropped.
    • Anything else (no "what", or under two usable options) gets one retry on the same quota and time budget, asking for a draft or a refusal.
    • An organizer who left is recorded as aborted.
  3. ev_008 copied Example C word for word. It's now a swim club prompt.
    • A new test fails when a worked example, or a rule's "e.g." text, matches an eval prompt, whole words only.
    • That test caught ev_034 too: it contained rule 4's "snack duty for the soccer team". It now says the basketball team.
  4. Harness bugs:
    • slot_dates.* now counts only real days, using the converter's own isRealDate. "TBD: date 1", a weekday or "TBD (2026-06-06)" no longer reads as a date.
    • The MCP check now passes a request with no "?" ("Please share the dates…", "I'll need…"). A refusal that closes with "Let me know what else…" still fails.
    • ev_031 needs a French bake-sale word. Articles, generic verbs and words English shares ("stand", "table") don't count, so English options fail.
    • ev_002 accepts a quantity or amount field.

Your call

  • ev_004 keeps drafting. A schedule of dated practices is the slots, so I changed the rule rather than the case.
  • Null capacity.
    • The schema line is now <integer, 1 by default; null only if the prompt or answers say there's no limit>.
    • Rule 9 now ends: No limit ("unlimited", "as many as want") means null; never null as a guess.
    • Item lists with a count (ev_002's 80 cookies) still get the count. The answers' "no limit" still maps to null.
  • Drafts on ev_001–027 slipped (83% vs 88%). I haven't changed anything for this on its own. Part of it is likely the over-asking above, so the next run should show whether it's still there.

Worth watching in the next run

  • ev_030 ("Team party on Saturday, June 5") should still ask, because of the new counter-case.
  • ev_004, ev_001–027 and ev_032–035 for over-asking.
  • How often capacity is null.
  • ev_008 and ev_034 with their new prompts.

#685 is noted as the follow-up.


Generated by Claude Code

@richshaw
richshaw merged commit 4b9299b into main Oct 27, 2026
7 checks passed
@richshaw
richshaw deleted the claude/pensive-thompson-quytut-5-prompt branch October 27, 2026 03:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Magic Compose drafts from a prompt too thin to build slots from, instead of asking for more

2 participants